package com.pulaien.shop.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.pulaien.common.core.domain.AjaxResult;
import com.pulaien.common.utils.StringUtils;
import com.pulaien.system.domain.ExchangeRate;
import com.pulaien.system.domain.dao.SysInternationalShippingDao;
import com.pulaien.system.domain.dao.SysModuleDao;
import com.pulaien.system.domain.dto.CalculateWeight;
import com.pulaien.system.domain.dto.CalculateWeightDto;
import com.pulaien.system.domain.dto.CalculateWeightFreightDto;
import com.pulaien.system.service.IExchangeRateService;
import com.pulaien.system.service.SysInternationalShippingService;
import com.pulaien.system.service.SysModuleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author yuanlai
 * @create 2024-01-15 9:47
 **/


@RestController
@RequestMapping("/shop/int/ship")
@Api(tags = "国际运费", description = "国际运费")
public class ShopInternationalShippingController {

    @Autowired
    private SysInternationalShippingService sysInternationalShippingService;

    @Autowired
    private SysModuleService sysModuleService;

    @Autowired
    private IExchangeRateService exchangeRateService;

    public ShopInternationalShippingController(SysInternationalShippingService sysInternationalShippingService, SysModuleService sysModuleService) {
        this.sysInternationalShippingService = sysInternationalShippingService;
        this.sysModuleService = sysModuleService;
    }

    @ApiOperation(value = "获取国际运费列表")
    @GetMapping("/getList")
    public AjaxResult getList() {
        List<SysModuleDao> moduleDaos = sysModuleService.list();
        List<SysInternationalShippingDao> internationalShippingList = new ArrayList<>();
        if (moduleDaos != null && moduleDaos.size() > 0) {
            List<Long> ids = moduleDaos.stream().map(SysModuleDao::getId).collect(Collectors.toList());
            QueryWrapper<SysInternationalShippingDao> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("del_flag", 0);
            queryWrapper.in("module_id", ids);
            queryWrapper.orderByAsc("create_time");
            internationalShippingList = sysInternationalShippingService.list(queryWrapper);
        }

        return AjaxResult.success(internationalShippingList);
    }


    @ApiOperation(value = "根据id获取国际运费")
    @GetMapping("/getId")
    public AjaxResult getInternationalShipping(@RequestParam Long id) {

        SysInternationalShippingDao byId = sysInternationalShippingService.getById(id);
        return AjaxResult.success(byId);
    }

    @ApiOperation(value = "计算国际运费")
    @PostMapping("/calculateWeight")
    public AjaxResult calculateWeight(@RequestBody CalculateWeightDto calculateWeightDto) throws IOException {

        List<CalculateWeight> calculateWeightList = calculateWeightDto.getCalculateWeightList();

        //最终返回的
        List<CalculateWeightFreightDto> calculateWeightFreightDtoList = new ArrayList<>();

        //汇率
        ExchangeRate exchangeRate = exchangeRateService.queryJpyExchangeRate();
        BigDecimal rate = exchangeRate.getExchangeRate();

        if (calculateWeightList == null) {
            return AjaxResult.error("体积和重量不能为空");
        }
        /*
            {
                settlementWeight: 0实际重量 1体积重量 2实际重量和体积重量取最大值,
                dividend:体积重量的被除数,
                logisticsCompanyName:物流公司名,
                logisticsCompanyCode:物流编码(自定义),
                weightAllocation:[
                    {
                        startWeight:重量范围开始(固定重量),
                        endWeight:重量范围结束,
                        type: 0固定重量固定价格 1区间重量 重量*单价 2固定重量 重量*单价,
                        unitPrice:单价,
                        sort:排序,
                        final:最终的重量价格 0不是 1是
                    }
                ]
            }
         */
        String path = "/json/shippingCalculator.json";
        //物流参数
        JSONArray jsonArray = new JSONArray();
        InputStream inputStream = getClass().getResourceAsStream(path);
        if (inputStream == null) {
            throw new RuntimeException("读取json文件失败！！！");
        } else {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

            StringBuilder stringBuilder = new StringBuilder();
            String line;

            while ((line = bufferedReader.readLine()) != null) {
                stringBuilder.append(line);
            }

            jsonArray = JSON.parseArray(stringBuilder.toString());
        }

        //体积
        BigDecimal volume = BigDecimal.ZERO;
        //实际重量
        BigDecimal weight = BigDecimal.ZERO;
        for (CalculateWeight calculateWeight : calculateWeightList) {
            if (calculateWeight.getWeight() != null) {
                weight = weight.add(calculateWeight.getWeight());
            }
            if (calculateWeight.getVolume() != null) {
                volume = volume.add(calculateWeight.getVolume());
            }
        }

        for (Object o : jsonArray) {
            JSONObject logistics = (JSONObject) o;
            //0实际重量 1体积重量 2实际重量和体积重量取最大值
            String settlementWeight = logistics.getString("settlementWeight");
            //体积重量
            BigDecimal volumeWeight = BigDecimal.ZERO;

            String dividend = logistics.getString("dividend");

            if (StringUtils.isNotBlank(dividend) && StringUtils.isNumeric(dividend)) {
                //获得体积重量 并且 不保留小数
                volumeWeight = volume.divide(BigDecimal.valueOf(Long.parseLong(dividend)), 0, BigDecimal.ROUND_UP);
            }

            //不保留小数
            weight = weight.setScale(0, BigDecimal.ROUND_UP);

            //结算重量
            BigDecimal resultWeight = BigDecimal.ZERO;

            if (settlementWeight.equals("0")) {
                resultWeight = weight;
            } else if (settlementWeight.equals("1")) {
                resultWeight = volumeWeight;
            } else {
                if (volumeWeight.compareTo(weight) > 0) {
                    resultWeight = volumeWeight;
                } else {
                    resultWeight = weight;
                }
            }

            //重量计算
            JSONArray weightAllocation = logistics.getJSONArray("weightAllocation");

            String logisticsCompanyName = logistics.getString("logisticsCompanyName");
            String logisticsCompanyCode = logistics.getString("logisticsCompanyCode");

            CalculateWeightFreightDto calculateWeightFreightDto = new CalculateWeightFreightDto();
            calculateWeightFreightDto.setResultWeight(resultWeight);
            calculateWeightFreightDto.setLogisticsCompanyName(logisticsCompanyName);
            calculateWeightFreightDto.setLogisticsCompanyCode(logisticsCompanyCode);

            for (Object object : weightAllocation) {
                JSONObject allocation = (JSONObject) object;
                //0固定重量固定价格 1区间重量 重量*单价 2固定重量 重量*单价
                String type = allocation.getString("type");
                //最终的重量价格 0不是 1是
                String finalPrice = allocation.getString("final");
                //单价
                BigDecimal unitPrice = allocation.getBigDecimal("unitPrice").setScale(2, BigDecimal.ROUND_UP);
                //重量范围开始(固定重量)
                BigDecimal startWeight = allocation.getBigDecimal("startWeight");
                //重量范围结束
                BigDecimal endWeight = allocation.getBigDecimal("endWeight");


                if (type.equals("0")) {
                    if (resultWeight.compareTo(startWeight) == 0) {
                        calculateWeightFreightDto.setFreightRmb(unitPrice);
                        BigDecimal freightJp = rate.multiply(unitPrice).setScale(0, BigDecimal.ROUND_UP);
                        calculateWeightFreightDto.setFreightJp(freightJp);
                        break;
                    }
                } else if (type.equals("1")) {
                    if (resultWeight.compareTo(startWeight) >= 0 && resultWeight.compareTo(endWeight) <= 0) {
                        BigDecimal multiply = resultWeight.multiply(unitPrice).setScale(2, BigDecimal.ROUND_UP);
                        calculateWeightFreightDto.setFreightRmb(multiply);

                        BigDecimal freightJp = rate.multiply(multiply).setScale(0, BigDecimal.ROUND_UP);
                        calculateWeightFreightDto.setFreightJp(freightJp);
                        break;
                    }

                    if (finalPrice.equals("1")) {
                        if (resultWeight.compareTo(startWeight) >= 0) {
                            BigDecimal multiply = resultWeight.multiply(unitPrice).setScale(2, BigDecimal.ROUND_UP);
                            calculateWeightFreightDto.setFreightRmb(multiply);

                            BigDecimal freightJp = rate.multiply(multiply).setScale(0, BigDecimal.ROUND_UP);
                            calculateWeightFreightDto.setFreightJp(freightJp);
                            break;
                        }
                    }

                } else if (type.equals("2")) {
                    if (resultWeight.compareTo(startWeight) == 0) {
                        BigDecimal multiply = resultWeight.multiply(unitPrice).setScale(2, BigDecimal.ROUND_UP);
                        calculateWeightFreightDto.setFreightRmb(multiply);

                        BigDecimal freightJp = rate.multiply(multiply).setScale(0, BigDecimal.ROUND_UP);
                        calculateWeightFreightDto.setFreightJp(freightJp);
                        break;
                    }
                }
            }
            calculateWeightFreightDtoList.add(calculateWeightFreightDto);
        }


        return AjaxResult.success(calculateWeightFreightDtoList);
    }

}
